package org.jxSwing.component.table;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;

import javax.swing.JComponent;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;

import org.jxUtils.lang.StringAsync;

/**
 * @author Denilson Edinaldo Pinto
 * @porject jxSwing
 * @package org.jxSwing.component.table
 * @date 09/04/2014 - 16:59:50
 */
public class LineNumberTable extends JComponent {
	
	private static final long serialVersionUID = -7963938014334261240L;
	
	private final JTable table;
	
	private final JScrollPane scrollPane;
	
	/**
	 * @param jScrollPane
	 * @param table
	 */
	public LineNumberTable(final JScrollPane jScrollPane, final JTable table) {
	
		scrollPane = jScrollPane;
		this.table = table;
		
		table.getModel().addTableModelListener(new TableModelListener() {
			
			@Override
			public void tableChanged(final TableModelEvent tme) {
			
				repaint();
			}
		});
		
		table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
			
			@Override
			public void valueChanged(final ListSelectionEvent lse) {
			
				repaint();
			}
		});
		
		scrollPane.getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener() {
			
			@Override
			public void adjustmentValueChanged(final AdjustmentEvent ae) {
			
				repaint();
			}
		});
		
		setPreferredSize(new Dimension(50, 100));
		setBackground(new Color(225, 225, 225));
	}
	
	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.swing.JComponent#paintComponent(java.awt.Graphics)
	 */
	@Override
	protected void paintComponent(final Graphics g) {
	
		final Point viewPosition = scrollPane.getViewport().getViewPosition();
		final Dimension viewSize = scrollPane.getViewport().getViewSize();
		
		//
		if(getHeight() < viewSize.height) {
			
			final Dimension size = getPreferredSize();
			
			size.height = viewSize.height;
			
			setSize(size);
			setPreferredSize(size);
		}
		
		super.paintComponent(g);
		
		//
		g.setColor(getBackground());
		g.fillRect(0, 0, getWidth(), getHeight());
		g.setFont(new Font(table.getFont().getName(), Font.BOLD, table.getFont().getSize()));
		
		final FontMetrics fm = g.getFontMetrics();
		
		final int rowCountNumberLength = String.valueOf(table.getRowCount()).length();
		
		//
		for(int r = 0; r < table.getRowCount(); r++) {
			
			final Rectangle cellRect = table.getCellRect(r, 0, false);
			
			final boolean rowSelected = table.isRowSelected(r);
			
			//
			if(rowSelected) {
				
				g.setColor(table.getSelectionBackground());
				g.fillRect(0, cellRect.y, getWidth(), cellRect.height);
			}
			
			//
			if(cellRect.y + cellRect.height - viewPosition.y >= 0 && cellRect.y < viewPosition.y + viewSize.height) {
				
				g.setColor(table.getGridColor());
				g.drawLine(0, cellRect.y + cellRect.height, getWidth(), cellRect.y + cellRect.height);
				g.setColor(rowSelected ? table.getSelectionForeground() : getForeground());
				
				String str = Integer.toString(r + 1);
				
				str = StringAsync.concat(str, "0", rowCountNumberLength - str.length(), true);
				
				final int x = (getWidth() - fm.stringWidth(str)) / 2;
				int y = fm.getHeight() * 2;
				
				//
				if(y > cellRect.height) {
					
					y = cellRect.y + fm.getHeight() + fm.getDescent();
					
				}else {
					
					y = cellRect.y + y;
				}
				
				g.drawString(str, x, y);
			}
		}
		
		//
		if(table.getShowVerticalLines()) {
			
			g.setColor(table.getGridColor());
			g.drawRect(0, 0, getWidth() - 1, getHeight() - 1);
		}
	}
}
